package seatiger.tomcat.coyote.http11;

import seatiger.tomcat.catalina.Connector;
import seatiger.tomcat.coyote.Adapter;
import seatiger.tomcat.coyote.ProtocolHandler;
import seatiger.tomcat.util.net.JIoEndpoint;
import seatiger.tomcat.util.net.ServerSocketFactory;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.Executor;

/**
 * 用于处理BIO的http请求
 */
public class Http11Protocol implements ProtocolHandler {

    protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);
    protected JIoEndpoint endpoint = new JIoEndpoint();
    protected ServerSocketFactory socketFactory;

    protected Connector connector;

    protected Adapter adapter;

    @Override
    public void init() throws Exception {
        endpoint.setHandler(cHandler);
        endpoint.setServerSocketFactory(socketFactory);
        endpoint.init();
    }

    @Override
    public void start() throws Exception {
        endpoint.start();
    }

    @Override
    public void setPort(int port) {
        endpoint.setPort(port);
    }

    @Override
    public void setExecutor(Executor executor) {
        endpoint.setExecutor(executor);
    }

    @Deprecated
    @Override
    public void setConnector(Connector connector) {
        this.connector = connector;
    }

    @Override
    public void destroy() throws Exception {
        endpoint.destroy();
    }

    @Override
    public void setAdapter(Adapter adapter) {
        this.adapter = adapter;
    }

    /**
     * 将Http11ConnectionHandler 作为Http11Protocol的内部类
     * HTTP1.1 处理连接请求
     */
    protected class Http11ConnectionHandler implements JIoEndpoint.Handler {
        protected Http11Protocol protocol;

        public Http11ConnectionHandler(Http11Protocol protocol) {
            this.protocol = protocol;
        }
        @Override
        public boolean process(Socket socket) {
            Http11Processor http11Processor = new Http11Processor();
            http11Processor.setAdapter(adapter);
            try {
                http11Processor.process(socket);
            }catch (IOException e){
                e.printStackTrace();
            }
            return false;
        }
    }
}
